package com.inplaceedit.client.ui.phone;

import java.util.HashMap;
import java.util.Map;

import com.google.gwt.editor.client.LeafValueEditor;
import com.google.gwt.editor.client.adapters.EditorSource;
import com.google.gwt.editor.client.adapters.ListEditor;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Widget;
import com.inplaceedit.client.ui.InPlaceEditPanel;
import com.inplaceedit.shared.dto.PhoneDto;

public class PhoneListDisplayView extends Composite implements PhoneListDisplay {

	private class PhoneEditorSource extends
			EditorSource<LeafValueEditor<PhoneDto>> {

		private final Map<LeafValueEditor<PhoneDto>, Widget> widgetIndex = new HashMap<LeafValueEditor<PhoneDto>, Widget>();
		private final Map<LeafValueEditor<PhoneDto>, HandlerRegistration> editHandlerIndex = new HashMap<LeafValueEditor<PhoneDto>, HandlerRegistration>();
		private final Map<LeafValueEditor<PhoneDto>, HandlerRegistration> deleteHandlerIndex = new HashMap<LeafValueEditor<PhoneDto>, HandlerRegistration>();

		@Override
		public LeafValueEditor<PhoneDto> create(final int index) {
			final PhoneDisplayView display = new PhoneDisplayView();
			final PhoneEditorView editor = new PhoneEditorView();
			final InPlaceEditPanel editPanel = new InPlaceEditPanel();

			editPanel.setDisplayWidget(display);
			editPanel.setEditorWidget(editor);
			editPanel.setDeleteCommandVisible(true);

			widgetIndex.put(display.asEditor(), editPanel);
			listPanel.insert(editPanel, index);

			editHandlerIndex.put(display.asEditor(), editPanel.getEditCommand()
					.addClickHandler(new ClickHandler() {
						@Override
						public void onClick(final ClickEvent event) {
							if (handler != null) {
								final int index = listPanel
										.getWidgetIndex(editPanel);
								if (index >= 0) {
									handler.onEdit(index, editor,
											editPanel.asDialog());
								}
							}
						}
					}));
			deleteHandlerIndex.put(display.asEditor(), editPanel
					.getDeleteCommand().addClickHandler(new ClickHandler() {
						@Override
						public void onClick(final ClickEvent event) {
							if (handler != null) {
								final int index = listPanel
										.getWidgetIndex(editPanel);
								if (index >= 0) {
									handler.onDelete(index);
								}
							}
						}
					}));

			return display.asEditor();
		}

		@Override
		public void dispose(final LeafValueEditor<PhoneDto> editor) {
			final HandlerRegistration editHandler = editHandlerIndex
					.get(editor);
			if (editHandler != null) {
				editHandler.removeHandler();
			}
			editHandlerIndex.remove(editor);

			final HandlerRegistration deleteHandler = deleteHandlerIndex
					.get(editor);
			if (editHandler != null) {
				deleteHandler.removeHandler();
			}
			deleteHandlerIndex.remove(editor);

			final Widget w = widgetIndex.get(editor);
			if (w != null) {
				listPanel.remove(w);
			}
			widgetIndex.remove(editor);
		}

		@Override
		public void setIndex(final LeafValueEditor<PhoneDto> editor,
				final int index) {
			final Widget w = widgetIndex.get(editor);
			if (w != null) {
				listPanel.insert(w, index);
			}
		}
	}

	private final FlowPanel listPanel;
	private final ListEditor<PhoneDto, LeafValueEditor<PhoneDto>> listEditor = ListEditor
			.of(new PhoneEditorSource());
	private Handler handler;

	public PhoneListDisplayView() {
		listPanel = new FlowPanel();
		initWidget(listPanel);
	}

	@Override
	public ListEditor<PhoneDto, LeafValueEditor<PhoneDto>> asEditor() {
		return listEditor;
	}

	@Override
	public void setHandler(final Handler handler) {
		this.handler = handler;
	}
}
